#include "jsontable/table_helper.h"
#include "struct_sobj.h"

template<> void LoadFromStream(SObjPrototype::Flags &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.isExclusiveMine, stream);
	StreamHelper::FromStream(entity.isRemoveAfterMineDone, stream);
	StreamHelper::FromStream(entity.isPlayerInteresting, stream);
	StreamHelper::FromStream(entity.isCreatureInteresting, stream);
	StreamHelper::FromStream(entity.isActivity, stream);
}

template<> void SaveToStream(const SObjPrototype::Flags &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.isExclusiveMine, stream);
	StreamHelper::ToStream(entity.isRemoveAfterMineDone, stream);
	StreamHelper::ToStream(entity.isPlayerInteresting, stream);
	StreamHelper::ToStream(entity.isCreatureInteresting, stream);
	StreamHelper::ToStream(entity.isActivity, stream);
}

template<> void LoadFromText(SObjPrototype::Flags &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const SObjPrototype::Flags &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(SObjPrototype::Flags &entity, const rapidjson::Value &value)
{
	FromJson(entity.isExclusiveMine, value, "isExclusiveMine");
	FromJson(entity.isRemoveAfterMineDone, value, "isRemoveAfterMineDone");
	FromJson(entity.isPlayerInteresting, value, "isPlayerInteresting");
	FromJson(entity.isCreatureInteresting, value, "isCreatureInteresting");
	FromJson(entity.isActivity, value, "isActivity");
}

template<> void JsonHelper::BlockToJson(const SObjPrototype::Flags &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.isExclusiveMine, value, "isExclusiveMine");
	ToJson(entity.isRemoveAfterMineDone, value, "isRemoveAfterMineDone");
	ToJson(entity.isPlayerInteresting, value, "isPlayerInteresting");
	ToJson(entity.isCreatureInteresting, value, "isCreatureInteresting");
	ToJson(entity.isActivity, value, "isActivity");
}

template<> void LoadFromStream(SObjPrototype::CostItem &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.itemId, stream);
	StreamHelper::FromStream(entity.itemNum, stream);
}

template<> void SaveToStream(const SObjPrototype::CostItem &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.itemId, stream);
	StreamHelper::ToStream(entity.itemNum, stream);
}

template<> void LoadFromText(SObjPrototype::CostItem &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const SObjPrototype::CostItem &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(SObjPrototype::CostItem &entity, const rapidjson::Value &value)
{
	FromJson(entity.itemId, value, "itemId");
	FromJson(entity.itemNum, value, "itemNum");
}

template<> void JsonHelper::BlockToJson(const SObjPrototype::CostItem &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.itemId, value, "itemId");
	ToJson(entity.itemNum, value, "itemNum");
}

template<> const char *GetTableName<SObjPrototype>()
{
	return "sobj_prototype";
}

template<> const char *GetTableKeyName<SObjPrototype>()
{
	return "sobjTypeId";
}

template<> uint32 GetTableKeyValue(const SObjPrototype &entity)
{
	return entity.sobjTypeId;
}

template<> void SetTableKeyValue(SObjPrototype &entity, uint32 key)
{
	entity.sobjTypeId = key;
}

template<> const char *GetTableFieldNameByIndex<SObjPrototype>(size_t index)
{
	switch (index)
	{
		case 0: return "sobjTypeId";
		case 1: return "sobjFlags";
		case 2: return "minRespawnTime";
		case 3: return "maxRespawnTime";
		case 4: return "teleportPointID";
		case 5: return "teleportDelayTime";
		case 6: return "lootSetID";
		case 7: return "mineSpellID";
		case 8: return "mineSpellLv";
		case 9: return "mineAnimTime";
		case 10: return "mineCostItems";
		case 11: return "sobjReqQuestDoing";
		case 12: return "radius";
		case 13: return "spawnScriptId";
		case 14: return "spawnScriptArgs";
		case 15: return "playScriptId";
		case 16: return "playScriptArgs";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<SObjPrototype>(const char *name)
{
	if (strcmp(name, "sobjTypeId") == 0) return 0;
	if (strcmp(name, "sobjFlags") == 0) return 1;
	if (strcmp(name, "minRespawnTime") == 0) return 2;
	if (strcmp(name, "maxRespawnTime") == 0) return 3;
	if (strcmp(name, "teleportPointID") == 0) return 4;
	if (strcmp(name, "teleportDelayTime") == 0) return 5;
	if (strcmp(name, "lootSetID") == 0) return 6;
	if (strcmp(name, "mineSpellID") == 0) return 7;
	if (strcmp(name, "mineSpellLv") == 0) return 8;
	if (strcmp(name, "mineAnimTime") == 0) return 9;
	if (strcmp(name, "mineCostItems") == 0) return 10;
	if (strcmp(name, "sobjReqQuestDoing") == 0) return 11;
	if (strcmp(name, "radius") == 0) return 12;
	if (strcmp(name, "spawnScriptId") == 0) return 13;
	if (strcmp(name, "spawnScriptArgs") == 0) return 14;
	if (strcmp(name, "playScriptId") == 0) return 15;
	if (strcmp(name, "playScriptArgs") == 0) return 16;
	return -1;
}

template<> size_t GetTableFieldNumber<SObjPrototype>()
{
	return 17;
}

template<> std::string GetTableFieldValue(const SObjPrototype &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.sobjTypeId);
		case 1: return JsonHelper::BlockToJsonText(entity.sobjFlags);
		case 2: return StringHelper::ToString(entity.minRespawnTime);
		case 3: return StringHelper::ToString(entity.maxRespawnTime);
		case 4: return StringHelper::ToString(entity.teleportPointID);
		case 5: return StringHelper::ToString(entity.teleportDelayTime);
		case 6: return StringHelper::ToString(entity.lootSetID);
		case 7: return StringHelper::ToString(entity.mineSpellID);
		case 8: return StringHelper::ToString(entity.mineSpellLv);
		case 9: return StringHelper::ToString(entity.mineAnimTime);
		case 10: return JsonHelper::BlockSequenceToJsonText(entity.mineCostItems);
		case 11: return StringHelper::ToString(entity.sobjReqQuestDoing);
		case 12: return StringHelper::ToString(entity.radius);
		case 13: return StringHelper::ToString(entity.spawnScriptId);
		case 14: return StringHelper::ToString(entity.spawnScriptArgs);
		case 15: return StringHelper::ToString(entity.playScriptId);
		case 16: return StringHelper::ToString(entity.playScriptArgs);
	}
	return "";
}

template<> void SetTableFieldValue(SObjPrototype &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.sobjTypeId, value);
		case 1: return JsonHelper::BlockFromJsonText(entity.sobjFlags, value);
		case 2: return StringHelper::FromString(entity.minRespawnTime, value);
		case 3: return StringHelper::FromString(entity.maxRespawnTime, value);
		case 4: return StringHelper::FromString(entity.teleportPointID, value);
		case 5: return StringHelper::FromString(entity.teleportDelayTime, value);
		case 6: return StringHelper::FromString(entity.lootSetID, value);
		case 7: return StringHelper::FromString(entity.mineSpellID, value);
		case 8: return StringHelper::FromString(entity.mineSpellLv, value);
		case 9: return StringHelper::FromString(entity.mineAnimTime, value);
		case 10: return JsonHelper::BlockSequenceFromJsonText(entity.mineCostItems, value);
		case 11: return StringHelper::FromString(entity.sobjReqQuestDoing, value);
		case 12: return StringHelper::FromString(entity.radius, value);
		case 13: return StringHelper::FromString(entity.spawnScriptId, value);
		case 14: return StringHelper::FromString(entity.spawnScriptArgs, value);
		case 15: return StringHelper::FromString(entity.playScriptId, value);
		case 16: return StringHelper::FromString(entity.playScriptArgs, value);
	}
}

template<> void LoadFromStream(SObjPrototype &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.sobjTypeId, stream);
	LoadFromStream(entity.sobjFlags, stream);
	StreamHelper::FromStream(entity.minRespawnTime, stream);
	StreamHelper::FromStream(entity.maxRespawnTime, stream);
	StreamHelper::FromStream(entity.teleportPointID, stream);
	StreamHelper::FromStream(entity.teleportDelayTime, stream);
	StreamHelper::FromStream(entity.lootSetID, stream);
	StreamHelper::FromStream(entity.mineSpellID, stream);
	StreamHelper::FromStream(entity.mineSpellLv, stream);
	StreamHelper::FromStream(entity.mineAnimTime, stream);
	StreamHelper::BlockSequenceFromStream(entity.mineCostItems, stream);
	StreamHelper::FromStream(entity.sobjReqQuestDoing, stream);
	StreamHelper::FromStream(entity.radius, stream);
	StreamHelper::FromStream(entity.spawnScriptId, stream);
	StreamHelper::FromStream(entity.spawnScriptArgs, stream);
	StreamHelper::FromStream(entity.playScriptId, stream);
	StreamHelper::FromStream(entity.playScriptArgs, stream);
}

template<> void SaveToStream(const SObjPrototype &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.sobjTypeId, stream);
	SaveToStream(entity.sobjFlags, stream);
	StreamHelper::ToStream(entity.minRespawnTime, stream);
	StreamHelper::ToStream(entity.maxRespawnTime, stream);
	StreamHelper::ToStream(entity.teleportPointID, stream);
	StreamHelper::ToStream(entity.teleportDelayTime, stream);
	StreamHelper::ToStream(entity.lootSetID, stream);
	StreamHelper::ToStream(entity.mineSpellID, stream);
	StreamHelper::ToStream(entity.mineSpellLv, stream);
	StreamHelper::ToStream(entity.mineAnimTime, stream);
	StreamHelper::BlockSequenceToStream(entity.mineCostItems, stream);
	StreamHelper::ToStream(entity.sobjReqQuestDoing, stream);
	StreamHelper::ToStream(entity.radius, stream);
	StreamHelper::ToStream(entity.spawnScriptId, stream);
	StreamHelper::ToStream(entity.spawnScriptArgs, stream);
	StreamHelper::ToStream(entity.playScriptId, stream);
	StreamHelper::ToStream(entity.playScriptArgs, stream);
}

template<> void LoadFromText(SObjPrototype &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const SObjPrototype &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(SObjPrototype &entity, const rapidjson::Value &value)
{
	FromJson(entity.sobjTypeId, value, "sobjTypeId");
	BlockFromJson(entity.sobjFlags, value, "sobjFlags");
	FromJson(entity.minRespawnTime, value, "minRespawnTime");
	FromJson(entity.maxRespawnTime, value, "maxRespawnTime");
	FromJson(entity.teleportPointID, value, "teleportPointID");
	FromJson(entity.teleportDelayTime, value, "teleportDelayTime");
	FromJson(entity.lootSetID, value, "lootSetID");
	FromJson(entity.mineSpellID, value, "mineSpellID");
	FromJson(entity.mineSpellLv, value, "mineSpellLv");
	FromJson(entity.mineAnimTime, value, "mineAnimTime");
	BlockSequenceFromJson(entity.mineCostItems, value, "mineCostItems");
	FromJson(entity.sobjReqQuestDoing, value, "sobjReqQuestDoing");
	FromJson(entity.radius, value, "radius");
	FromJson(entity.spawnScriptId, value, "spawnScriptId");
	FromJson(entity.spawnScriptArgs, value, "spawnScriptArgs");
	FromJson(entity.playScriptId, value, "playScriptId");
	FromJson(entity.playScriptArgs, value, "playScriptArgs");
}

template<> void JsonHelper::BlockToJson(const SObjPrototype &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.sobjTypeId, value, "sobjTypeId");
	BlockToJson(entity.sobjFlags, value, "sobjFlags");
	ToJson(entity.minRespawnTime, value, "minRespawnTime");
	ToJson(entity.maxRespawnTime, value, "maxRespawnTime");
	ToJson(entity.teleportPointID, value, "teleportPointID");
	ToJson(entity.teleportDelayTime, value, "teleportDelayTime");
	ToJson(entity.lootSetID, value, "lootSetID");
	ToJson(entity.mineSpellID, value, "mineSpellID");
	ToJson(entity.mineSpellLv, value, "mineSpellLv");
	ToJson(entity.mineAnimTime, value, "mineAnimTime");
	BlockSequenceToJson(entity.mineCostItems, value, "mineCostItems");
	ToJson(entity.sobjReqQuestDoing, value, "sobjReqQuestDoing");
	ToJson(entity.radius, value, "radius");
	ToJson(entity.spawnScriptId, value, "spawnScriptId");
	ToJson(entity.spawnScriptArgs, value, "spawnScriptArgs");
	ToJson(entity.playScriptId, value, "playScriptId");
	ToJson(entity.playScriptArgs, value, "playScriptArgs");
}

template<> void LoadFromStream(StaticObjectSpawn::Flags &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.isRespawn, stream);
}

template<> void SaveToStream(const StaticObjectSpawn::Flags &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.isRespawn, stream);
}

template<> void LoadFromText(StaticObjectSpawn::Flags &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const StaticObjectSpawn::Flags &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(StaticObjectSpawn::Flags &entity, const rapidjson::Value &value)
{
	FromJson(entity.isRespawn, value, "isRespawn");
}

template<> void JsonHelper::BlockToJson(const StaticObjectSpawn::Flags &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.isRespawn, value, "isRespawn");
}

template<> const char *GetTableName<StaticObjectSpawn>()
{
	return "staticobject_spawn";
}

template<> const char *GetTableKeyName<StaticObjectSpawn>()
{
	return "spawnId";
}

template<> uint32 GetTableKeyValue(const StaticObjectSpawn &entity)
{
	return entity.spawnId;
}

template<> void SetTableKeyValue(StaticObjectSpawn &entity, uint32 key)
{
	entity.spawnId = key;
}

template<> const char *GetTableFieldNameByIndex<StaticObjectSpawn>(size_t index)
{
	switch (index)
	{
		case 0: return "spawnId";
		case 1: return "flags";
		case 2: return "entry";
		case 3: return "map_id";
		case 4: return "map_type";
		case 5: return "x";
		case 6: return "y";
		case 7: return "z";
		case 8: return "o";
		case 9: return "radius";
	}
	return "";
}

template<> ssize_t GetTableFieldIndexByName<StaticObjectSpawn>(const char *name)
{
	if (strcmp(name, "spawnId") == 0) return 0;
	if (strcmp(name, "flags") == 0) return 1;
	if (strcmp(name, "entry") == 0) return 2;
	if (strcmp(name, "map_id") == 0) return 3;
	if (strcmp(name, "map_type") == 0) return 4;
	if (strcmp(name, "x") == 0) return 5;
	if (strcmp(name, "y") == 0) return 6;
	if (strcmp(name, "z") == 0) return 7;
	if (strcmp(name, "o") == 0) return 8;
	if (strcmp(name, "radius") == 0) return 9;
	return -1;
}

template<> size_t GetTableFieldNumber<StaticObjectSpawn>()
{
	return 10;
}

template<> std::string GetTableFieldValue(const StaticObjectSpawn &entity, size_t index)
{
	switch (index)
	{
		case 0: return StringHelper::ToString(entity.spawnId);
		case 1: return JsonHelper::BlockToJsonText(entity.flags);
		case 2: return StringHelper::ToString(entity.entry);
		case 3: return StringHelper::ToString(entity.map_id);
		case 4: return StringHelper::ToString(entity.map_type);
		case 5: return StringHelper::ToString(entity.x);
		case 6: return StringHelper::ToString(entity.y);
		case 7: return StringHelper::ToString(entity.z);
		case 8: return StringHelper::ToString(entity.o);
		case 9: return StringHelper::ToString(entity.radius);
	}
	return "";
}

template<> void SetTableFieldValue(StaticObjectSpawn &entity, size_t index, const std::string_view &value)
{
	switch (index)
	{
		case 0: return StringHelper::FromString(entity.spawnId, value);
		case 1: return JsonHelper::BlockFromJsonText(entity.flags, value);
		case 2: return StringHelper::FromString(entity.entry, value);
		case 3: return StringHelper::FromString(entity.map_id, value);
		case 4: return StringHelper::FromString(entity.map_type, value);
		case 5: return StringHelper::FromString(entity.x, value);
		case 6: return StringHelper::FromString(entity.y, value);
		case 7: return StringHelper::FromString(entity.z, value);
		case 8: return StringHelper::FromString(entity.o, value);
		case 9: return StringHelper::FromString(entity.radius, value);
	}
}

template<> void LoadFromStream(StaticObjectSpawn &entity, std::istream &stream)
{
	StreamHelper::FromStream(entity.spawnId, stream);
	LoadFromStream(entity.flags, stream);
	StreamHelper::FromStream(entity.entry, stream);
	StreamHelper::FromStream(entity.map_id, stream);
	StreamHelper::FromStream(entity.map_type, stream);
	StreamHelper::FromStream(entity.x, stream);
	StreamHelper::FromStream(entity.y, stream);
	StreamHelper::FromStream(entity.z, stream);
	StreamHelper::FromStream(entity.o, stream);
	StreamHelper::FromStream(entity.radius, stream);
}

template<> void SaveToStream(const StaticObjectSpawn &entity, std::ostream &stream)
{
	StreamHelper::ToStream(entity.spawnId, stream);
	SaveToStream(entity.flags, stream);
	StreamHelper::ToStream(entity.entry, stream);
	StreamHelper::ToStream(entity.map_id, stream);
	StreamHelper::ToStream(entity.map_type, stream);
	StreamHelper::ToStream(entity.x, stream);
	StreamHelper::ToStream(entity.y, stream);
	StreamHelper::ToStream(entity.z, stream);
	StreamHelper::ToStream(entity.o, stream);
	StreamHelper::ToStream(entity.radius, stream);
}

template<> void LoadFromText(StaticObjectSpawn &entity, const char *text)
{
	JsonHelper::BlockFromJsonText(entity, text);
}

template<> std::string SaveToText(const StaticObjectSpawn &entity)
{
	return JsonHelper::BlockToJsonText(entity);
}

template<> void JsonHelper::BlockFromJson(StaticObjectSpawn &entity, const rapidjson::Value &value)
{
	FromJson(entity.spawnId, value, "spawnId");
	BlockFromJson(entity.flags, value, "flags");
	FromJson(entity.entry, value, "entry");
	FromJson(entity.map_id, value, "map_id");
	FromJson(entity.map_type, value, "map_type");
	FromJson(entity.x, value, "x");
	FromJson(entity.y, value, "y");
	FromJson(entity.z, value, "z");
	FromJson(entity.o, value, "o");
	FromJson(entity.radius, value, "radius");
}

template<> void JsonHelper::BlockToJson(const StaticObjectSpawn &entity, rapidjson::Value &value)
{
	SetJsonObjectValue(value);
	ToJson(entity.spawnId, value, "spawnId");
	BlockToJson(entity.flags, value, "flags");
	ToJson(entity.entry, value, "entry");
	ToJson(entity.map_id, value, "map_id");
	ToJson(entity.map_type, value, "map_type");
	ToJson(entity.x, value, "x");
	ToJson(entity.y, value, "y");
	ToJson(entity.z, value, "z");
	ToJson(entity.o, value, "o");
	ToJson(entity.radius, value, "radius");
}
